package com.lord.otter.component.infrastructure.template.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import org.springframework.util.CollectionUtils;

import java.util.Collection;
import java.util.List;
import java.util.Objects;

import static com.lord.otter.component.exception.CommonExceptionEnum.LACK_PARAM;
import static com.lord.otter.component.exception.CommonExceptionEnum.OBJ_NOT_FOUND;

/**
 * 命令服务 模板
 *
 * @author lord
 * 2025/8/26 13:36
 */
public interface CommandServiceTemplate {

    /**
     * 命令转换
     * 默认 简单 实现
     *
     * @param command            协议层命令
     * @param domainCommandClass 领域命令类型
     * @return 领域命令
     * @author lord
     * 2025/8/26 13:37
     */
    default <T, R> R commandConvert(T command, Class<R> domainCommandClass) {
        ensureNonNull(command);
        ensureNonNull(domainCommandClass);
        return BeanUtil.toBean(command, domainCommandClass);
    }

    /**
     * 命令转换
     * 默认 简单 实现
     *
     * @param commands           协议层命令
     * @param domainCommandClass 领域命令类型
     * @author lord
     * 2025/8/26 17:23
     */
    default <T, R> List<R> commandConvert(List<T> commands, Class<R> domainCommandClass) {
        ensureNonNulls(commands);
        ensureNonNull(domainCommandClass);
        return BeanUtil.copyToList(commands, domainCommandClass);
    }


    /**
     * 确保非空
     *
     * @param commands 命令
     * @author lord
     * 2025/8/26 13:37
     */
    default <T> void ensureNonNulls(Collection<T> commands) {
        if (CollectionUtils.isEmpty(commands)) {
            throw LACK_PARAM.exceptionDefault();
        }
        for (Object command : commands) {
            ensureNonNull(command);
        }
    }

    default void ensureNonNull(Object command) {
        ensureNonNull(command, LACK_PARAM.getMessage());
    }

    default void ensureNonNull(Object command, String message) {
        ensureNonNull(command, message, (String) null);
    }

    default void ensureNonNull(Object command, String message, String... args) {
        ensureNonNull(command, LACK_PARAM.exceptionMessageArgs(message, args));
    }

    default void ensureNonNull(Object command, RuntimeException exception) {
        if (command == null) {
            throw exception;
        }
    }


    /**
     * 确保查询结果非空
     *
     * @param obj 查询结果
     * @author lord
     * 2025/8/26 13:37
     */
    default void ensureQueryResultNonNull(Object obj) {
        ensureQueryResultNonNull(obj, null, (String) null);
    }

    default void ensureQueryResultNonNull(Object obj, String message) {
        ensureQueryResultNonNull(obj, message, (String) null);
    }

    default <T> T ensureObjectNonNull(T t) {
        return ensureQueryResultNonNull(t, null, (String) null);
    }

    default <T> T ensureObjectNonNull(T t, String message) {
        return ensureQueryResultNonNull(t, message, (String) null);
    }

    default <T> List<T> ensureListNonNull(List<T> list) {
        if (CollectionUtils.isEmpty(list)) {
            throw OBJ_NOT_FOUND.exceptionDefault();
        }
        return list;
    }

    default <T> T ensureQueryResultNonNull(T t, String message, String... args) {
        if (Objects.isNull(t)) {
            if (StrUtil.isBlank(message)) {
                throw OBJ_NOT_FOUND.exceptionDefault();
            } else {
                throw OBJ_NOT_FOUND.exceptionMessageArgs(message, args);
            }
        }
        return t;
    }
}
